package cn.jsc.service.impl;

import ch.qos.logback.core.net.SyslogOutputStream;
import cn.jsc.dto.sendSmsCodeDto;
import cn.jsc.exception.MyException;
import cn.jsc.result.JSONResult;
import cn.jsc.service.IVerifyCodeService;
import cn.jsc.utils.MyTools;
import cn.jsc.utils.VerifyCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * 1. 请求图片验证码之前判断SessionStorage是否有KEY,
 *    如果没就创建，然后保存SessionStorage,如果有自己直接作为参数发送Ajax请求获取图片验证码
 * 2. 前端通过ajax发送一个图片验证码请求,携带者KEY
 * 3. 后端收到请求，生成图片验证码的值
 * 4. 把图片验证码的值存储到Redis，以前段传入的key作为Redis的key
 * 5. 把图片验证码的值合并到一个图片中
 * 6. 把图片基于Base64编码层字符串，响应给前端
 * 7. 前端拿到base64字符串，进行图片的展示，用户输入图片验证码
 * 8. 前台提交注册请求 ，验证图片验证码(key也要携带)，
 *    后端把前端传入的图片验证码的值和Redis中的图片验证码的值做比较
 */
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 获取图片验证码
     * 逻辑：
     * 1、校验key
     * 2、生成随机的四位数，并且存入Redis（key就是入参key）
     * 3、生成图片，并将随机数水印上去
     * 4、将图片进行base64编码，结果返回
     */
    @Override
    public String createImageCode(String key) {
        //1、校验key
        if(!StringUtils.hasLength(key)){
            throw new MyException("UUID不为空！");
        }
        //2.1生成随机的四位数，并且存入Redis（key就是入参key）
        //调用工具类MyTools 生成4位随机数
        String code = MyTools.getRandomNum(4);
        //2.2存入Redis（key就是入参key）
        redisTemplate.opsForValue().set(key,code,2, TimeUnit.MINUTES);//设置过期时间2分钟

        //3、生成图片，并将随机数水印上去 将图片进行base64编码，结果返回
        //通过生成图片验证码工具类VerifyCodeUtils，设置图片的长宽和需要水印的随机数
        String imgBase64  = VerifyCodeUtils.verifyCode(130, 35, code);

        //4.结果返回
        return imgBase64;
    }

    /**
     * 获取短信验证码
     * 1. 将如下信息传入后台接口：手机号、用户输入的图片验证码、UUID
     * 2. 接口编码逻辑：
     *    1. 根据UUID到Redis获取验证码，如果没有，说明有人搞事情，返回报错；
     *       如果取到数据了，比对
     *    2. 比对成功，调用第三方接口发送短信，需要包含6位数的验证码
     *      （用工具类生成6位数的验证码并且存入Redis）
     * @param dto
     * @return
     */
    @Override
    public JSONResult sendSmsCode(sendSmsCodeDto dto) {
        //1、校验入参

        //2、先查询数据库，看手机号是否注册

        //3、校验图片验证码输入是否正确
        //获取redis里面的验证码
        String code = (String)redisTemplate.opsForValue().get(dto.getImageCodeKey());

        if(!StringUtils.hasLength(code)){
            //如果redis里面没有验证码值，抛出异常
            throw new MyException("请重新刷新图片验证码输入！");
        }

        if(!code.equalsIgnoreCase(dto.getImageCode())){//equalsIgnoreCase: 忽略大小写
            //如果redis里面的验证码与用户输入的不一样，抛出异常
            throw new MyException("验证码输入错误，请重新输入！");
        }

        //验证码输入正确，获取短信验证码 随机6位，调用工具类
        String smsCode = MyTools.getRandomNum(6);
        String msg = "尊敬的["+dto.getMobile()+"],您的验证码为:"+smsCode;
        //调用接口发送短信
        System.out.println(msg);
        //存入redis
        redisTemplate.opsForValue().set(dto.getMobile(),smsCode,60,TimeUnit.SECONDS);//存1分钟
        return JSONResult.success();
    }
}
